package com.crysta1.aitrans;

import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.text.TextUtils;
import android.util.Log;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;

/**
 * PttCalculator - 潜力值（PTT）计算工具类
 *
 * 责任：
 *  - 计算单次潜力分值 (singlePotential = score * difficultyWeight)
 *  - 获取最近 N 条记录的 singlePotential 列表 (含 timestamp, id)
 *  - 按截止 (timestamp, id) 计算潜力值（inclusive 控制是否包含该 id，便于 before/after 计算）
 *  - 统一应用去除 top5/bottom5 的规则（在样本较少时会尽量剔除但不留空）
 *
 * 返回值范围：1.0 - 10.0
 *
 * 使用示例：
 *   PttCalculator calc = new PttCalculator(dbHelper);
 *   float potAll = calc.computePotentialForAll(); // 当前整体潜力
 *   float potBefore = calc.computePotentialUpTo(db, ts, id, false);
 *   float potAfter = calc.computePotentialUpTo(db, ts, id, true);
 */
public class PttCalculator {
    private static final String TAG = "PttCalculator";

    private final DatabaseHelper dbHelper;
    private final DecimalFormat df = new DecimalFormat("0.00");

    public PttCalculator(DatabaseHelper dbHelper) {
        this.dbHelper = dbHelper;
    }

    /**
     * 单次潜力分计算：score * weight(difficulty)
     */
    public float computeSinglePotential(float score, String difficulty) {
        float weight = getWeightForDifficulty(difficulty);
        return score * weight;
    }

    /**
     * 获取最近 limit 条记录的单次潜力（按 timestamp DESC）
     * 返回列表按时间降序（最新在前）
     */
    public List<SinglePotentialEntry> getRecentSinglePotentials(int limit) {
        List<SinglePotentialEntry> out = new ArrayList<>();
        SQLiteDatabase db = dbHelper.getReadableDatabase();
        String sql = "SELECT " + DatabaseHelper.COLUMN_ID + ", " + DatabaseHelper.COLUMN_SCORE + ", "
                + DatabaseHelper.COLUMN_DIFFICULTY + ", " + DatabaseHelper.COLUMN_TIMESTAMP
                + " FROM " + DatabaseHelper.TABLE_QUIZ_RECORDS
                + " ORDER BY " + DatabaseHelper.COLUMN_TIMESTAMP + " DESC, " + DatabaseHelper.COLUMN_ID + " DESC"
                + " LIMIT " + limit;
        Cursor c = db.rawQuery(sql, null);
        if (c != null) {
            while (c.moveToNext()) {
                long id = c.isNull(0) ? 0L : c.getLong(0);
                float score = c.isNull(1) ? 0f : c.getFloat(1);
                String diff = c.isNull(2) ? null : c.getString(2);
                long ts = c.isNull(3) ? 0L : c.getLong(3);
                float sp = computeSinglePotential(score, diff);
                out.add(new SinglePotentialEntry(id, score, diff, sp, ts));
            }
            c.close();
        }
        return out;
    }

    /**
     * 计算截止到 (ts, id)（并按 inclusive 决定是否包含该 id）的潜力值。
     * 规则：获取满足条件的最近最多 60 条记录（按 timestamp DESC, id DESC），
     * 然后对 singlePotential 排序并去除最多5个最大与5个最小（若可行），剩余项平均 -> 限制在 [1,10]
     *
     * 注：调用时传入 dbHelper.getReadableDatabase() 更高效（如果你已经有 db 实例）
     */
    public float computePotentialUpTo(SQLiteDatabase db, long ts, long id, boolean inclusive) {
        List<Float> singlePotentials = new ArrayList<>();

        String op = inclusive ? "<=" : "<";
        String sql = "SELECT " + DatabaseHelper.COLUMN_SCORE + ", " + DatabaseHelper.COLUMN_DIFFICULTY + " FROM "
                + DatabaseHelper.TABLE_QUIZ_RECORDS
                + " WHERE (" + DatabaseHelper.COLUMN_TIMESTAMP + " < ? OR ( " + DatabaseHelper.COLUMN_TIMESTAMP + " = ? AND "
                + DatabaseHelper.COLUMN_ID + " " + op + " ? ))"
                + " ORDER BY " + DatabaseHelper.COLUMN_TIMESTAMP + " DESC, " + DatabaseHelper.COLUMN_ID + " DESC"
                + " LIMIT 60";

        Cursor cur = db.rawQuery(sql, new String[]{String.valueOf(ts), String.valueOf(ts), String.valueOf(id)});
        if (cur != null) {
            while (cur.moveToNext()) {
                if (cur.isNull(0)) continue;
                float score = cur.getFloat(0);
                String diff = cur.isNull(1) ? null : cur.getString(1);
                float sp = computeSinglePotential(score, diff);
                singlePotentials.add(sp);
            }
            cur.close();
        }

        if (singlePotentials.isEmpty()) {
            Log.d(TAG, "computePotentialUpTo: no records found for ts=" + ts + " id=" + id + " inclusive=" + inclusive);
            return 1.0f;
        }

        Collections.sort(singlePotentials); // 从小到大
        int total = singlePotentials.size();
        int removeTop = Math.min(5, total / 2);
        int removeBottom = Math.min(5, total / 2);

        // 确保剔除后至少保留 1 个
        while (total - removeTop - removeBottom <= 0) {
            if (removeTop > 0) removeTop--;
            if (removeBottom > 0 && total - removeTop - removeBottom > 0) break;
            if (removeBottom > 0) removeBottom--;
            if (removeTop == 0 && removeBottom == 0) break;
        }

        int start = removeBottom;
        int end = total - removeTop; // exclusive

        float sum = 0f;
        int count = 0;
        for (int i = start; i < end; i++) {
            sum += singlePotentials.get(i);
            count++;
        }

        float avg;
        if (count > 0) avg = sum / count;
        else { // 极端容错：用所有项平均
            float tsum = 0f;
            for (float v : singlePotentials) tsum += v;
            avg = tsum / total;
        }

        if (avg < 1.0f) avg = 1.0f;
        if (avg > 10.0f) avg = 10.0f;

        Log.d(TAG, String.format(Locale.getDefault(),
                "computePotentialUpTo ts=%d id=%d inclusive=%b total=%d remBottom=%d remTop=%d remain=%d avg=%.4f",
                ts, id, inclusive, total, removeBottom, removeTop, count, avg));

        return avg;
    }

    /**
     * 计算当前整体潜力（包含所有现有记录）
     */
    public float computePotentialForAll() {
        SQLiteDatabase db = dbHelper.getReadableDatabase();
        return computePotentialUpTo(db, Long.MAX_VALUE, Long.MAX_VALUE, true);
    }

    /**
     * 格式化潜力为保留两位小数的字符串
     */
    public String formatPotential(float pot) {
        return df.format(pot);
    }

    /**
     * 支持的 SinglePotential 数据容器
     */
    public static class SinglePotentialEntry {
        public final long id;
        public final float score;
        public final String difficulty;
        public final float singlePotential;
        public final long timestamp;

        public SinglePotentialEntry(long id, float score, String difficulty, float singlePotential, long timestamp) {
            this.id = id;
            this.score = score;
            this.difficulty = difficulty;
            this.singlePotential = singlePotential;
            this.timestamp = timestamp;
        }

        @Override
        public String toString() {
            return "id=" + id + " score=" + score + " diff=" + (TextUtils.isEmpty(difficulty) ? "-" : difficulty)
                    + " sp=" + singlePotential + " ts=" + timestamp;
        }
    }

    /**
     * 难度转权重（与之前约定一致）
     */
    private float getWeightForDifficulty(String difficulty) {
        if (difficulty == null) return 1.0f;
        String d = difficulty.trim().toLowerCase(Locale.ROOT);
        switch (d) {
            case "简单":
            case "e":
            case "easy":
                return 0.5f;
            case "适中":
            case "m":
            case "medium":
                return 0.8f;
            case "困难":
            case "h":
            case "hard":
                return 1.0f;
            case "仿真":
            case "r":
            case "real":
            case "simulation":
                return 1.1f;
            default:
                if (d.startsWith("e")) return 0.5f;
                if (d.startsWith("m")) return 0.8f;
                if (d.startsWith("h")) return 1.0f;
                if (d.startsWith("r")) return 1.1f;
                return 1.0f;
        }
    }
}
